home *** CD-ROM | disk | FTP | other *** search
- //
- // Copyright 1999 Macromedia, Inc. All rights reserved.
- // -----------------------------------------------------
- //
- // DOM.js
- //
- // This file contains some general helper functions for working with
- // the Dreamweaver DOM.
- //
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Function
- // getRootNode
- //
- // Purpose
- // Quickie function for getting the root node of the active document.
- //
- function getRootNode()
- {
- return dreamweaver.getDocumentDOM("document").documentElement;
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // Function
- // findTag
- //
- // Purpose
- // Find a tag with the given name. The search starts at startNode and
- // searches its children.
- //
- // Entry
- // tagName - a string that contains the name of the tag to find.
- // startNode - the node in the dom to start from. If this is not
- // given, the root node will be used by default.
- //
- function findTag(tagName) // optional: startNode
- {
- var startNode = (findTag.arguments.length >= 2 ? findTag.arguments[1] : null);
- var i, result;
-
- if(startNode == null)
- startNode = getRootNode();
-
- if(startNode.tagName != null &&
- startNode.tagName.toUpperCase() == tagName.toUpperCase())
- return startNode;
-
- for(i = 0; i < startNode.childNodes.length; i++)
- {
- result = findTag(tagName, startNode.childNodes[i]);
-
- if(result != null)
- return result; // found it.
- }
-
- return null; // didn't find it here.
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- // Function
- // traverse
- //
- // Purpose
- // Given a node, this will traverse the entire DOM structure, calling
- // a handler (callback) function for each node type that it encounters.
- //
- function traverse( node, fElementHandler ) // optional: fTextHandler, fCommentHandler, userData )
- {
- if(node == null)
- node = getRootNode();
-
- var fTextHandler = traverse.arguments.length >= 3 ? traverse.arguments[2] : null;
- var fCommentHandler = traverse.arguments.length >= 4 ? traverse.arguments[3] : null;
- var userData = traverse.arguments.length >= 5 ? traverse.arguments[4] : null;
- var children = node.childNodes;
- var nChildren = children.length;
- var bContinue = true;
- var current = null;
-
- if(fElementHandler == null && fTextHandler == null && fCommentHandler == null) return; // No callbacks. Nothing to do.
-
- for( var i = 0; bContinue && (i < nChildren); i++ )
- {
- current = children.item( i );
-
- // descend to any children first
- if ( current.hasChildNodes() )
- traverse( current, fElementHandler, fTextHandler, fCommentHandler, userData );
-
- // process current node
- switch( current.nodeType )
- {
- case Node.ELEMENT_NODE:
- if(fElementHandler != null)
- if ( userData != null )
- bContinue = fElementHandler( current, userData );
- else
- bContinue = fElementHandler( current );
- break;
-
- case Node.COMMENT_NODE:
- if ( fCommentHandler != null )
- if ( userData != null )
- bContinue = fCommentHandler( current, userData );
- else
- bContinue = fCommentHandler( current );
- break;
-
- case Node.TEXT_NODE:
- if ( fTextHandler != null )
- if ( userData != null )
- bContinue = fTextHandler( current, userData )
- else
- bContinue = fTextHandler( current )
- break;
-
- case Node.DOCUMENT_NODE:
- default:
- MM_error( MSG_UnknownNodeType, current.nodeType );
- }
- }
- }
-
-
- //////////////////////////////////////////////////////////////////////////////
- // Function
- // isInsideTag
- //
- // Purpose
- // Check to see if a given tag is contained within another tag.
- //
- // Parameters
- // tag - the tag in the DOM for which to check
- // tagNames - a comma delimited list of tags to search for.
- // (ie "p,h1,h2,h3,h4,h5,h6"). No spaces.
- //
- // Returns
- // true if the tag is contained within one of the given tags.
- //
- function isInsideTag(tag, tagNames)
- {
- var tagList = tagNames.split(",");
- var regx = new RegExp();
- var parent, result;
-
- for(i = 0; i < tagList.length; i++)
- {
- parent = tag.parentNode;
- regx.compile(tagList[i], "i");
-
- while(parent != null)
- {
- result = regx.exec(parent.tagName);
-
- if(result != null)
- return true;
-
- parent = parent.parentNode;
- }
- }
-
- return false;
- }
-
-
- //Popups up a command. Before popping it up, updates globals. Command can then
- //use these globals to get and receive arguments from the caller.
-
- function callCommand(cmdName,argObject) {
- MM.commandArgument = argObject;
- MM.commandReturnValue = null;
- dw.popupCommand(cmdName);
- return MM.commandReturnValue;
- }
-
-
-
- //************** FUNCTIONS FOR UPDATING BEHAVIOR CODE ****************8
-
- var DW_VERSION = 3.0;
-
- //Checks if function is latest, and maybe updates it. If out of date (and first caller),
- //refresh all behaviors on page. Returns true if behavior was out of date.
-
- function updateBehaviorFns() {
- var behNames = updateBehaviorFns.arguments;
- var retVal = false;
- var fnVerOnPage, fnVersion;
-
- for (i=0; i<behNames.length; i++) { //with each name passed in...
- fnVersion = document["VERSION_"+behNames[i]]; //if fn has defined document.VERSION_MM_fnName, get it
- if (!fnVersion) fnVersion = DW_VERSION; //if not defined, use general Dreamweaver version
- fnVerOnPage = getFunctionVersion(behNames[i]); //get version of the function in user's page
- if (fnVerOnPage > -1 && fnVerOnPage < fnVersion) { //if fn out of date
- deleteFunction(behNames[i]); //delete older fn
- retVal = true;
- } }
- if (retVal) { //if any function was updated, refresh all the behavior calls on the page
- var DOM = dw.getDocumentDOM();
- if (DOM) {
- DOM.reapplyBehaviors();
- } }
- return retVal;
- }
-
- //Used by behaviors to see if behavior function already exists on the page, and
- //if so, what version it is. Given a function name, returns the version (if
- //it exists on the first line as //v3.123) or 0 if no version. Returns -1 if
- //the function is not found on the page. For example, given function
- // function myFunction() { //v2.0
- //Calling getFunctionVersion("myFunction") returns 2. Given function
- // function myFunction() {
- //Calling getFunctionVersion("myFunction") returns 0.
- //Searches dom if passed, else searches active document.
- //Does not search included src files (use dom to do this).
- //
- //Arguments: fnName, dom (optional). If no dom, searches current page
- //Returns -1 if function not found, 0 if found without version number.
-
- function getFunctionVersion(fnName, dom) {
- if (!dom) dom = dreamweaver.getDocumentDOM("document");
- var i, aScript, result, version=-1;
- var allScripts = dom.getElementsByTagName("SCRIPT");
- var fnPatt = new RegExp("function\\s+" + fnName + "\\s*\\(.+$"); //find function fnName(...); ...\n
- var verPatt = new RegExp("\\/\\/v(\\d+\\.?\\d*)","i"); //find //v3.123
-
- for (i=0; i<allScripts.length; i++) if (allScripts[i].hasChildNodes()) {
- aScript = allScripts[i].childNodes[0].data; //read script tag
- RegExp.multiline = true; //required so that $ stops at the end of the line
- result = aScript.match(fnPatt);
- RegExp.multiline = false; //reset the value
- if (result) {
- version = 0;
- aScript = result[0];
- result = aScript.match(verPatt); //find //v3.123
- if (result) version = parseFloat(result[1]);
- break;
- } }
- return version;
- }
-
-
- //Used by behaviors to remove older versions of behavior functions.
- //Deletes a function with a given name from the document.
- //IMPORTANT! Will not work if function contains braces {} within quotes.
- //Does not search included src files (use dom to do this).
- //
- //Arguments: fnName, dom (optional). If no dom, searches current page
- //Returns: empty string if function not found, otherwise returns deleted function
-
- function deleteFunction(fnName, dom) {
- if (!dom) dom = dreamweaver.getDocumentDOM("document");
- var i, j, aScript, startPos, curChar, braceCount, retVal=false;
- var allScripts = dom.getElementsByTagName("SCRIPT");
- var fnPatt = new RegExp("function\\s+" + fnName + "\\s*\\("); //find function fnName(...{
-
- for (i=0; i<allScripts.length; i++) if (allScripts[i].hasChildNodes()) {
- aScript = allScripts[i].childNodes[0].data;
- startPos = aScript.search(fnPatt);
- if (startPos != -1) { //found function, start traversing
- for (j=startPos; aScript.charAt(j) != "{"; j++); //find first brace
- j++;
- braceCount=1;
- while (braceCount>0 && j<aScript.length) { //count braces until 0
- curChar = aScript.charAt(j++);
- if (curChar=="{") braceCount++;
- if (curChar=="}") braceCount--;
- }
- if (braceCount == 0) {
- while (aScript.charAt(j).search(/\s/) != -1) j++; //remove trailing whitespace
- retVal = (aScript.substring(startPos,j)); //return the chunk to delete
- allScripts[i].childNodes[0].data = aScript.substring(0,startPos) + aScript.substring(j); //delete it!
- }
- break;
- } }
- return retVal;
- }
-
-
-
-
- //Used by behaviors to remove old function call.
- //Deletes a function call with a given name from the document.
- //Does not search included src files (use dom to do this).
- //Requires function to have closing semicolon.
- //
- //Arguments: fnName, dom (optional). If no dom, searches current page
- //Returns: false if function call not found, otherwise returns script node in which it was deleted.
-
- function deleteFunctionCall(fnName, dom) {
- if (!dom) dom = dreamweaver.getDocumentDOM("document");
- var i, j, aScript, startPos, retVal=false;
- var allScripts = dom.getElementsByTagName("SCRIPT");
- var fnPatt = new RegExp("\\s+" + fnName + "\\s*\\("); //find function fnName(...{
-
- for (i=0; i<allScripts.length; i++) if (allScripts[i].hasChildNodes()) {
- aScript = allScripts[i].childNodes[0].data;
- startPos = aScript.search(fnPatt);
- if (startPos != -1) { //found function, start traversing
- for (j=startPos; j<aScript.length-1 && aScript.charAt(j) != ";"; j++); //find closing semicolon
- if (aScript.charAt(j) == ";") { //if semicolon found
- retVal = aScript.substring(startPos,j); //return the deleted string.
- aScript = aScript.substring(0,startPos) + aScript.substring(j+1);
- if (scriptIsEmpty(aScript)) { // Remove the entire script if it is empty.
- allScripts[i].outerHTML = '';
- } else {
- allScripts[i].childNodes[0].data = aScript; //delete it!
- }
- }
- break;
- } }
- return retVal;
- }
-
- //Tests for the exisitence of a function call.
- //Does not search included src files (use dom to do this).
- //
- //Arguments: fnName, dom (optional). If no dom, searches current page
- //Returns: false if function call not found, otherwise true.
-
- function hasFunctionCall(fnName, dom) {
- if (!dom) dom = dreamweaver.getDocumentDOM("document");
- var retVal=false;
- var allScripts = dom.getElementsByTagName("SCRIPT");
- var fnPatt = new RegExp("\\s+" + fnName + "\\s*\\("); //find function fnName(...{
-
- for (var i=0; i<allScripts.length; i++) {
- if (fnPatt.test(allScripts[i].innerHTML)) {
- retVal = true;
- break;
- }
- }
- return retVal;
- }
-
-
-
- // Determine if script is empty. Check for just white space
- // and a standard javascript comment tag.
- //Arguments: String (which should be the contents of a script tag.
- //Returns: true if the script contains only empty commments, otherwise false.
-
- function scriptIsEmpty(aScript) {
- var re = /^\s*(<!--+)*\s*(\/\/+\s*--+>)*\s*$/;
- return re.test(aScript);
- }